home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / BorderLayout.java < prev    next >
Text File  |  1998-09-22  |  16KB  |  471 lines

  1. /*
  2.  * @(#)BorderLayout.java    1.32 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt;
  16.  
  17. import java.util.Hashtable;
  18.  
  19. /**
  20.  * A border layout lays out a container, arranging and resizing
  21.  * its components to fit in five regions:
  22.  * <code>North</code>, <code>South</code>, <code>East</code>, 
  23.  * <code>West</code>, and <code>Center</code>.  When adding a 
  24.  * component to a container with a border layout, use one of these
  25.  * five names, for example:
  26.  * <pre>
  27.  *    Panel p = new Panel();
  28.  *    p.setLayout(new BorderLayout());
  29.  *    p.add(new Button("Okay"), "South");
  30.  * </pre>
  31.  * As a convenience, BorderLayout interprets the absence of a string
  32.  * specification the same as "Center":
  33.  * <pre>
  34.  *    Panel p2 = new Panel();
  35.  *    p2.setLayout(new BorderLayout());
  36.  *    p2.add(new TextArea());  // Same as p.add(new TextArea(), "Center");
  37.  * </pre>
  38.  * <p>
  39.  * The components are laid out according to their 
  40.  * preferred sizes and the constraints of the container's size. 
  41.  * The <code>North</code> and <code>South</code> components may 
  42.  * be stretched horizontally; the <code>East</code> and 
  43.  * <code>West</code> components may be stretched vertically; 
  44.  * the <code>Center</code> component may stretch both horizontally 
  45.  * and vertically to fill any space left over. 
  46.  * <p>
  47.  * Here is an example of five buttons in an applet laid out using 
  48.  * the <code>BorderLayout</code> layout manager:
  49.  * <p>
  50.  * <img src="images-awt/BorderLayout-1.gif"
  51.  * ALIGN=center HSPACE=10 VSPACE=7>
  52.  * <p>
  53.  * The code for this applet is as follows: 
  54.  * <p>
  55.  * <hr><blockquote><pre>
  56.  * import java.awt.*;
  57.  * import java.applet.Applet;
  58.  * 
  59.  * public class buttonDir extends Applet {
  60.  *   public void init() {
  61.  *     setLayout(new BorderLayout());
  62.  *     add("North",  new Button("North"));
  63.  *     add("South",  new Button("South"));
  64.  *     add("East",   new Button("East"));
  65.  *     add("West",   new Button("West"));
  66.  *     add("Center", new Button("Center"));
  67.  *   }
  68.  * }
  69.  * </pre></blockquote><hr>
  70.  * <p>
  71.  * @version     1.27 02/11/97
  72.  * @author     Arthur van Hoff
  73.  * @see         java.awt.Container.add(String, Component)
  74.  * @since       JDK1.0
  75.  */
  76. public class BorderLayout implements LayoutManager2,
  77.                      java.io.Serializable {
  78.     int hgap;
  79.     int vgap;
  80.  
  81.     Component north;
  82.     Component west;
  83.     Component east;
  84.     Component south;
  85.     Component center;
  86.  
  87.     /**
  88.      * The north layout constraint (top of container).
  89.      */
  90.     public static final String NORTH  = "North";
  91.  
  92.     /**
  93.      * The south layout constraint (bottom of container).
  94.      */
  95.     public static final String SOUTH  = "South";
  96.  
  97.     /**
  98.      * The east layout constraint (left side of container).
  99.      */
  100.     public static final String EAST   = "East";
  101.  
  102.     /**
  103.      * The west layout constraint (right side of container).
  104.      */
  105.     public static final String WEST   = "West";
  106.  
  107.     /**
  108.      * The center layout constraint (middle of container).
  109.      */
  110.     public static final String CENTER = "Center";
  111.  
  112.     /*
  113.      * JDK 1.1 serialVersionUID 
  114.      */
  115.      private static final long serialVersionUID = -8658291919501921765L;
  116.  
  117.     /**
  118.      * Constructs a new border layout with  
  119.      * no gaps between components.
  120.      * @since     JDK1.0
  121.      */
  122.     public BorderLayout() {
  123.     this(0, 0);
  124.     }
  125.  
  126.     /**
  127.      * Constructs a border layout with the specified gaps 
  128.      * between components.
  129.      * The horizontal gap is specified by <code>hgap</code> 
  130.      * and the vertical gap is specified by <code>vgap</code>.
  131.      * @param   hgap   the horizontal gap.
  132.      * @param   vgap   the vertical gap.    
  133.      * @since   JDK1.0
  134.      */    
  135.     public BorderLayout(int hgap, int vgap) {
  136.     this.hgap = hgap;
  137.     this.vgap = vgap;
  138.     }
  139.  
  140.     /**
  141.      * Returns the horizontal gap between components.
  142.      * @since   JDK1.1
  143.      */
  144.     public int getHgap() {
  145.     return hgap;
  146.     }
  147.     
  148.     /**
  149.      * Sets the horizontal gap between components.
  150.      * @param hgap the horizontal gap between components
  151.      * @since   JDK1.1
  152.      */
  153.     public void setHgap(int hgap) {
  154.     this.hgap = hgap;
  155.     }
  156.     
  157.     /**
  158.      * Returns the vertical gap between components.
  159.      * @since   JDK1.1
  160.      */
  161.     public int getVgap() {
  162.     return vgap;
  163.     }
  164.     
  165.     /**
  166.      * Sets the vertical gap between components.
  167.      * @param vgap the vertical gap between components
  168.      * @since   JDK1.1
  169.      */
  170.     public void setVgap(int vgap) {
  171.     this.vgap = vgap;
  172.     }
  173.  
  174.     /**
  175.      * Adds the specified component to the layout, using the specified
  176.      * constraint object.  For border layouts, the constraint must be
  177.      * one of the following strings:  <code>"North"</code>,
  178.      * <code>"South"</code>, <code>"East"</code>,
  179.      * <code>"West"</code>, or <code>"Center"</code>.  
  180.      * <p>
  181.      * Most applications do not call this method directly. This method 
  182.      * is called when a component is added to a container using the 
  183.      * <code>Container.add</code> method with the same argument types.
  184.      * @param   comp         the component to be added.
  185.      * @param   constraints  an object that specifies how and where 
  186.      *                       the component is added to the layout.
  187.      * @see     java.awt.Container#add(java.awt.Component, java.lang.Object)
  188.      * @exception   IllegalArgumentException  if the constraint object is not
  189.      *                 a string, or if it not one of the five specified strings.
  190.      * @since   JDK1.1
  191.      */
  192.     public void addLayoutComponent(Component comp, Object constraints) {
  193.       synchronized (comp.getTreeLock()) {
  194.     if ((constraints == null) || (constraints instanceof String)) {
  195.         addLayoutComponent((String)constraints, comp);
  196.     } else {
  197.         throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
  198.     }
  199.       }
  200.     }
  201.  
  202.     /**
  203.      * @deprecated  replaced by <code>addLayoutComponent(Component, Object)</code>.
  204.      */
  205.     public void addLayoutComponent(String name, Component comp) {
  206.       synchronized (comp.getTreeLock()) {
  207.     /* Special case:  treat null the same as "Center". */
  208.     if (name == null) {
  209.         name = "Center";
  210.     }
  211.  
  212.     /* Assign the component to one of the known regions of the layout.
  213.      */
  214.     if ("Center".equals(name)) {
  215.         center = comp;
  216.     } else if ("North".equals(name)) {
  217.         north = comp;
  218.     } else if ("South".equals(name)) {
  219.         south = comp;
  220.     } else if ("East".equals(name)) {
  221.         east = comp;
  222.     } else if ("West".equals(name)) {
  223.         west = comp;
  224.     } else {
  225.         throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
  226.     }
  227.       }
  228.     }
  229.  
  230.     /**
  231.      * Removes the specified component from this border layout. This 
  232.      * method is called when a container calls its <code>remove</code> or 
  233.      * <code>removeAll</code> methods. Most applications do not call this 
  234.      * method directly. 
  235.      * @param   comp   the component to be removed.
  236.      * @see     java.awt.Container#remove(java.awt.Component)
  237.      * @see     java.awt.Container#removeAll()
  238.      * @since   JDK1.0
  239.      */
  240.     public void removeLayoutComponent(Component comp) {
  241.       synchronized (comp.getTreeLock()) {
  242.     if (comp == center) {
  243.         center = null;
  244.     } else if (comp == north) {
  245.         north = null;
  246.     } else if (comp == south) {
  247.         south = null;
  248.     } else if (comp == east) {
  249.         east = null;
  250.     } else if (comp == west) {
  251.         west = null;
  252.     }
  253.       }
  254.     }
  255.  
  256.     /**
  257.      * Determines the minimum size of the <code>target</code> container 
  258.      * using this layout manager. 
  259.      * <p>
  260.      * This method is called when a container calls its 
  261.      * <code>getMinimumSize</code> method. Most applications do not call 
  262.      * this method directly. 
  263.      * @param   target   the container in which to do the layout.
  264.      * @return  the minimum dimensions needed to lay out the subcomponents 
  265.      *          of the specified container.
  266.      * @see     java.awt.Container  
  267.      * @see     java.awt.BorderLayout#preferredLayoutSize
  268.      * @see     java.awt.Container#getMinimumSize()
  269.      * @since   JDK1.0
  270.      */
  271.     public Dimension minimumLayoutSize(Container target) {
  272.       synchronized (target.getTreeLock()) {
  273.     Dimension dim = new Dimension(0, 0);
  274.  
  275.     if ((east != null) && east.visible) {
  276.         Dimension d = east.getMinimumSize();
  277.         dim.width += d.width + hgap;
  278.         dim.height = Math.max(d.height, dim.height);
  279.     }
  280.     if ((west != null) && west.visible) {
  281.         Dimension d = west.getMinimumSize();
  282.         dim.width += d.width + hgap;
  283.         dim.height = Math.max(d.height, dim.height);
  284.     }
  285.     if ((center != null) && center.visible) {
  286.         Dimension d = center.getMinimumSize();
  287.         dim.width += d.width;
  288.         dim.height = Math.max(d.height, dim.height);
  289.     }
  290.     if ((north != null) && north.visible) {
  291.         Dimension d = north.getMinimumSize();
  292.         dim.width = Math.max(d.width, dim.width);
  293.         dim.height += d.height + vgap;
  294.     }
  295.     if ((south != null) && south.visible) {
  296.         Dimension d = south.getMinimumSize();
  297.         dim.width = Math.max(d.width, dim.width);
  298.         dim.height += d.height + vgap;
  299.     }
  300.  
  301.     Insets insets = target.getInsets();
  302.     dim.width += insets.left + insets.right;
  303.     dim.height += insets.top + insets.bottom;
  304.  
  305.     return dim;
  306.       }
  307.     }
  308.     
  309.     /**
  310.      * Determines the preferred size of the <code>target</code> 
  311.      * container using this layout manager, based on the components
  312.      * in the container. 
  313.      * <p>
  314.      * Most applications do not call this method directly. This method
  315.      * is called when a container calls its <code>getPreferredSize</code> 
  316.      * method.
  317.      * @param   target   the container in which to do the layout.
  318.      * @return  the preferred dimensions to lay out the subcomponents 
  319.      *          of the specified container.
  320.      * @see     java.awt.Container  
  321.      * @see     java.awt.BorderLayout#minimumLayoutSize  
  322.      * @see     java.awt.Container#getPreferredSize()
  323.      * @since   JDK1.0
  324.      */
  325.     public Dimension preferredLayoutSize(Container target) {
  326.       synchronized (target.getTreeLock()) {
  327.     Dimension dim = new Dimension(0, 0);
  328.  
  329.     if ((east != null) && east.visible) {
  330.         Dimension d = east.getPreferredSize();
  331.         dim.width += d.width + hgap;
  332.         dim.height = Math.max(d.height, dim.height);
  333.     }
  334.     if ((west != null) && west.visible) {
  335.         Dimension d = west.getPreferredSize();
  336.         dim.width += d.width + hgap;
  337.         dim.height = Math.max(d.height, dim.height);
  338.     }
  339.     if ((center != null) && center.visible) {
  340.         Dimension d = center.getPreferredSize();
  341.         dim.width += d.width;
  342.         dim.height = Math.max(d.height, dim.height);
  343.     }
  344.     if ((north != null) && north.visible) {
  345.         Dimension d = north.getPreferredSize();
  346.         dim.width = Math.max(d.width, dim.width);
  347.         dim.height += d.height + vgap;
  348.     }
  349.     if ((south != null) && south.visible) {
  350.         Dimension d = south.getPreferredSize();
  351.         dim.width = Math.max(d.width, dim.width);
  352.         dim.height += d.height + vgap;
  353.     }
  354.  
  355.     Insets insets = target.getInsets();
  356.     dim.width += insets.left + insets.right;
  357.     dim.height += insets.top + insets.bottom;
  358.  
  359.     return dim;
  360.       }
  361.     }
  362.  
  363.     /**
  364.      * Returns the maximum dimensions for this layout given the components
  365.      * in the specified target container.
  366.      * @param target the component which needs to be laid out
  367.      * @see Container
  368.      * @see #minimumLayoutSize
  369.      * @see #preferredLayoutSize
  370.      */
  371.     public Dimension maximumLayoutSize(Container target) {
  372.     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  373.     }
  374.  
  375.     /**
  376.      * Returns the alignment along the x axis.  This specifies how
  377.      * the component would like to be aligned relative to other 
  378.      * components.  The value should be a number between 0 and 1
  379.      * where 0 represents alignment along the origin, 1 is aligned
  380.      * the furthest away from the origin, 0.5 is centered, etc.
  381.      */
  382.     public float getLayoutAlignmentX(Container parent) {
  383.     return 0.5f;
  384.     }
  385.  
  386.     /**
  387.      * Returns the alignment along the y axis.  This specifies how
  388.      * the component would like to be aligned relative to other 
  389.      * components.  The value should be a number between 0 and 1
  390.      * where 0 represents alignment along the origin, 1 is aligned
  391.      * the furthest away from the origin, 0.5 is centered, etc.
  392.      */
  393.     public float getLayoutAlignmentY(Container parent) {
  394.     return 0.5f;
  395.     }
  396.  
  397.     /**
  398.      * Invalidates the layout, indicating that if the layout manager
  399.      * has cached information it should be discarded.
  400.      */
  401.     public void invalidateLayout(Container target) {
  402.     }
  403.                       
  404.     /**
  405.      * Lays out the container argument using this border layout. 
  406.      * <p>
  407.      * This method actually reshapes the components in the specified
  408.      * container in order to satisfy the constraints of this 
  409.      * <code>BorderLayout</code> object. The <code>North</code> 
  410.      * and <code>South</code>components, if any, are placed at 
  411.      * the top and bottom of the container, respectively. The 
  412.      * <code>West</code> and <code>East</code> components are 
  413.      * then placed on the left and right, respectively. Finally, 
  414.      * the <code>Center</code> object is placed in any remaining 
  415.      * space in the middle. 
  416.      * <p>
  417.      * Most applications do not call this method directly. This method 
  418.      * is called when a container calls its <code>doLayout</code> method. 
  419.      * @param   target   the container in which to do the layout.
  420.      * @see     java.awt.Container  
  421.      * @see     java.awt.Container#doLayout()
  422.      * @since   JDK1.0
  423.      */
  424.     public void layoutContainer(Container target) {
  425.       synchronized (target.getTreeLock()) {
  426.     Insets insets = target.getInsets();
  427.     int top = insets.top;
  428.     int bottom = target.height - insets.bottom;
  429.     int left = insets.left;
  430.     int right = target.width - insets.right;
  431.  
  432.     if ((north != null) && north.visible) {
  433.         north.setSize(right - left, north.height);
  434.         Dimension d = north.getPreferredSize();
  435.         north.setBounds(left, top, right - left, d.height);
  436.         top += d.height + vgap;
  437.     }
  438.     if ((south != null) && south.visible) {
  439.         south.setSize(right - left, south.height);
  440.         Dimension d = south.getPreferredSize();
  441.         south.setBounds(left, bottom - d.height, right - left, d.height);
  442.         bottom -= d.height + vgap;
  443.     }
  444.     if ((east != null) && east.visible) {
  445.         east.setSize(east.width, bottom - top);
  446.         Dimension d = east.getPreferredSize();
  447.         east.setBounds(right - d.width, top, d.width, bottom - top);
  448.         right -= d.width + hgap;
  449.     }
  450.     if ((west != null) && west.visible) {
  451.         west.setSize(west.width, bottom - top);
  452.         Dimension d = west.getPreferredSize();
  453.         west.setBounds(left, top, d.width, bottom - top);
  454.         left += d.width + hgap;
  455.     }
  456.     if ((center != null) && center.visible) {
  457.         center.setBounds(left, top, right - left, bottom - top);
  458.     }
  459.       }
  460.     }
  461.     
  462.     /**
  463.      * Returns a string representation of the state of this border layout.
  464.      * @return    a string representation of this border layout.
  465.      * @since     JDK1.0
  466.      */
  467.     public String toString() {
  468.     return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
  469.     }
  470. }
  471.